package com.yonyou.crm.sys.modules.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.yonyou.crm.base.doc.entity.BaseDocDetailVO;
import com.yonyou.crm.base.doc.entity.BaseDocVO;
import com.yonyou.crm.bpub.detail.entity.DetailsGroupVO;
import com.yonyou.crm.bpub.detail.entity.DetailsItemVO;
import com.yonyou.crm.bpub.initData.entity.InitDatasBodyVO;
import com.yonyou.crm.bpub.initData.entity.InitDatasItemVO;
import com.yonyou.crm.bpub.initData.entity.InitDatasListItemVO;
import com.yonyou.crm.bpub.initData.entity.InitDatasVO;
import com.yonyou.crm.bpub.template.entity.TemplatesBodyVO;
import com.yonyou.crm.bpub.template.entity.TemplatesEnumVO;
import com.yonyou.crm.bpub.template.entity.TemplatesFilterVO;
import com.yonyou.crm.bpub.template.entity.TemplatesHeaderVO;
import com.yonyou.crm.bpub.template.entity.TemplatesItemVO;
import com.yonyou.crm.bpub.template.entity.TemplatesParttakeVO;
import com.yonyou.crm.bpub.template.entity.TemplatesTriggerVO;
import com.yonyou.crm.bpub.template.entity.TemplatesVO;
import com.yonyou.crm.common.biz.service.BaseBizServiceImpl;
import com.yonyou.crm.common.exception.CrmBusinessException;
import com.yonyou.crm.common.login.context.LoginContextConstant;
import com.yonyou.crm.sys.modules.constants.ClientType;
import com.yonyou.crm.sys.modules.constants.FieldType;
import com.yonyou.crm.sys.modules.constants.LayoutType;
import com.yonyou.crm.sys.modules.entity.ApiVO;
import com.yonyou.crm.sys.modules.entity.BiztypeVO;
import com.yonyou.crm.sys.modules.entity.BlockItemVO;
import com.yonyou.crm.sys.modules.entity.BlockVO;
import com.yonyou.crm.sys.modules.entity.FieldVO;
import com.yonyou.crm.sys.modules.entity.ItemLayoutItemVO;
import com.yonyou.crm.sys.modules.entity.LayoutAssignmentVO;
import com.yonyou.crm.sys.modules.entity.LayoutVO;
import com.yonyou.crm.sys.modules.entity.ModuleVO;
import com.yonyou.crm.sys.modules.entity.RelationLayoutVO;
import com.yonyou.crm.sys.modules.events.BiztypeDeleteEvent;
import com.yonyou.crm.sys.modules.events.FieldDeleteEvent;
import com.yonyou.crm.sys.role.entity.RoleVO;
import com.yonyou.crm.sys.role.service.RoleBizServiceImpl;

import static com.yonyou.crm.sys.modules.util.MobileAdapter.*;

import com.yonyou.iuap.context.InvocationInfoProxy;

@Service
public class LayoutBizServiceImpl extends BaseBizServiceImpl<LayoutVO>{

	@Autowired
	private CustomIdGeneratorBizServiceImpl customIdGeneratorBizServiceImpl;
	
	@Autowired
	private BlockBizServiceImpl blockServiceImpl;
	
	@Autowired
	private BiztypeBizServiceImpl biztypeBizServiceImpl;
	
	@Autowired
	private RoleBizServiceImpl roleBizServiceImpl;
	
	@Autowired
	private ModuleBizServiceImpl moduleServiceImpl;
	
	@Autowired
	private ItemLayoutBizServiceImpl itemLayoutServiceImpl;
	
	@Autowired
	private RelationLayoutBizServiceImpl relationLayoutBizServiceImpl;
	
	@Autowired
	private AdministratorManage administratorManage;
	
	@Autowired 
	private ModuleBizServiceImpl moduleBizServiceImpl;
	
	/**
	 * 获取模板列表
	 * 
	 * @return
	 */
	public List<LayoutVO> getLayoutList(Long objId) {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		paramMap.put("tenantId", tenantId);
		paramMap.put("objId", objId);

		List<LayoutVO> layoutList = new ArrayList<LayoutVO>();
		layoutList = dao.selectVoList(LayoutVO.class, "ListLayout", paramMap);
		List<Long> customLayouts = new ArrayList<Long>();
		for (LayoutVO layoutVO : layoutList) {
			if (layoutVO.getTenantId() != 0) {
				customLayouts.add(layoutVO.getId());
			}
		}
		Iterator<LayoutVO> it = layoutList.iterator();
		while (it.hasNext()) {
			LayoutVO layout = it.next();
			if ((layout.getTenantId() == 0 && customLayouts.contains(layout.getId())) 
					|| layout.getIsDeleted() ==1) {
				    it.remove();
			}
			//查询业务类型
			BiztypeVO biztype = biztypeBizServiceImpl.getBiztype(layout.getBiztypeId());
			layout.setBiztypeName(biztype.getName());
		}
		return layoutList;
	}
	
	public LayoutVO getLayout(Long id) {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		paramMap.put("tenantId", tenantId);
		paramMap.put("id", id);
		List<LayoutVO> layoutList = new ArrayList<LayoutVO>();
		layoutList = dao.selectVoList(LayoutVO.class, "ListLayout", paramMap);
		LayoutVO layoutVO = null;
		Iterator<LayoutVO> it = layoutList.iterator();
		while (it.hasNext()) {
			layoutVO  = it.next();
			if (layoutVO.getTenantId() != 0) {
				break;
			}
		}
		//查询业务类型
		BiztypeVO biztype = biztypeBizServiceImpl.getBiztype(layoutVO.getBiztypeId());
		layoutVO.setBiztypeName(biztype.getName());
		List<BlockVO> blockVOs = blockServiceImpl.getBlockList(id);
		layoutVO.setMainLayout(blockVOs);
		ModuleVO moduleVO = moduleServiceImpl.getModule(layoutVO.getObjId());
		if (moduleVO.getWithItem() == 1) {
			List<ItemLayoutItemVO> itemLayoutItemVOs = itemLayoutServiceImpl.getItemLayout(id);
			layoutVO.setItemLayout(itemLayoutItemVOs);
		} else {
			layoutVO.setItemLayout(null);
		}
		List<RelationLayoutVO> relationLayoutVOs = null;
		// 如果布局修改过(根据tenantId判断)，则关联对象配置取最新的，即如果没有关联对象配置，则表明全勾掉了，
		// 如果没修改过，则关联对象配置取默认配置
		if (layoutVO.getTenantId() == 0) {
			relationLayoutVOs = relationLayoutBizServiceImpl.getLayoutList(0L, layoutVO);
		} else {
			relationLayoutVOs = relationLayoutBizServiceImpl.getLayoutList(tenantId, layoutVO);
		}
		layoutVO.setRelationLayout(relationLayoutVOs);
		transformForClient(layoutVO);
		return layoutVO;
	}
	
	public LayoutVO saveLayout(LayoutVO layoutVO) {
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		String userIdStr = (String)InvocationInfoProxy.getParameter("id");//用户id
		Long userId = Long.parseLong(userIdStr);
		
		Long layoutId = getNextId();
		layoutVO.setTenantId(tenantId);
		layoutVO.setId(layoutId);
		Date now = new Date();
		Date createDate = (layoutVO.getCreatedTime() == null) ? now :layoutVO.getCreatedTime() ;
		Date modifyDate = (layoutVO.getModifiedTime() == null) ? now :layoutVO.getModifiedTime() ;
		Long createUserId   = (layoutVO.getCreatedUserId() == null) ? userId :layoutVO.getCreatedUserId() ;
		Long modifyUserId   = (layoutVO.getModifiedUserId() == null) ? userId :layoutVO.getModifiedUserId() ;	
		layoutVO.setEnableState(1);//1代表默认启用状态
		layoutVO.setEnableTime(now);
		layoutVO.setEnableUserId(userId);
		layoutVO.setIsDefault(0);
		layoutVO.setSortOrder(now.getTime());
		layoutVO.setCreatedTime(createDate);
		layoutVO.setModifiedTime(modifyDate);
		layoutVO.setCreatedUserId(createUserId);
		layoutVO.setModifiedUserId(modifyUserId);
		layoutVO.setSysCreatedTime(now);
		layoutVO.setSysModifiedTime(now);
		layoutVO.setSysCreatedUserId(userId);
		layoutVO.setSysModifiedUserId(userId);
		super.saveVO(layoutVO);
		
		//查询业务类型
		BiztypeVO biztype = biztypeBizServiceImpl.getBiztype(layoutVO.getBiztypeId());
		layoutVO.setBiztypeName(biztype.getName());
		//增加主对象布局
		ModuleVO moduleVO = moduleServiceImpl.getModule(layoutVO.getObjId());
		List<BlockVO> blockVOList = layoutVO.getMainLayout();
		
		for (int i =0; i < blockVOList.size(); i++) {
			BlockVO blockVO = blockVOList.get(i);
			blockVO.setLayoutId(layoutId);
			blockServiceImpl.addBlock(moduleVO,blockVO);
		}
		
		// 增加明细对象布局
		if (layoutVO.getItemLayout() != null && layoutVO.getItemLayout().size() > 0) {
			ModuleVO itemModuleVO = moduleServiceImpl.getModule(layoutVO.getObjId()).getItem();

			itemLayoutServiceImpl.deleteItemLayout(layoutId, itemModuleVO.getId());
			itemLayoutServiceImpl.saveItemLayout( layoutVO,itemModuleVO);
		}
		
		// 新增相关对象布局
		if (layoutVO.getRelationLayout() != null && layoutVO.getRelationLayout().size() > 0) {
			for (int i =0 ; i < layoutVO.getRelationLayout().size() ; i++) {
				RelationLayoutVO relationLayoutVO = layoutVO.getRelationLayout().get(i);
				relationLayoutVO.setLayoutId(layoutId);
			}
			relationLayoutBizServiceImpl.deleteLayouts(layoutId);
			relationLayoutBizServiceImpl.addLayouts(layoutVO.getRelationLayout());
		}
		return layoutVO;
	}
	
	
	public LayoutVO updateLayout(LayoutVO layoutVO) {
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		String userIdStr = (String)InvocationInfoProxy.getParameter("id");//用户id
		Long userId = Long.parseLong(userIdStr);
		Long layoutId = layoutVO.getId();
		Date now = new Date();
		layoutVO.setTenantId(tenantId);
		layoutVO.setModifiedTime(now);
		layoutVO.setModifiedUserId(userId);
		layoutVO.setSysModifiedTime(now);
		layoutVO.setSysModifiedUserId(userId);
		LayoutVO originalLayoutVO = getLayout(layoutVO.getId());
		layoutVO.setIsDefault(originalLayoutVO.getIsDefault());
		// 如果是修改系统预置布局，则从系统预置布局复制一份
		if (originalLayoutVO.getTenantId() ==0) {
			layoutVO.setIsDefault(1);
			layoutVO.setSysCreatedTime(now);
			layoutVO.setSysCreatedUserId(userId);
			layoutVO.setCreatedTime(originalLayoutVO.getCreatedTime());
			layoutVO.setCreatedUserId(originalLayoutVO.getCreatedUserId());
			layoutVO.setObjId(originalLayoutVO.getObjId());
			layoutVO.setType(originalLayoutVO.getType());
			layoutVO.setClientType(originalLayoutVO.getClientType());
			layoutVO.setSortOrder(originalLayoutVO.getSortOrder());
			super.saveVO(layoutVO);
		} else {
			super.updateVO(layoutVO);
		}
		//查询业务类型
		BiztypeVO biztype = biztypeBizServiceImpl.getBiztype(layoutVO.getBiztypeId());
		layoutVO.setBiztypeName(biztype.getName());
		
		//增加主对象布局,先删后增
		ModuleVO moduleVO = moduleServiceImpl.getModule(originalLayoutVO.getObjId());
		blockServiceImpl.deleteAllBlocks(layoutId);
		List<BlockVO> blockVOList = layoutVO.getMainLayout();
		for (int i =0; i < blockVOList.size(); i++) {
			BlockVO blockVO = blockVOList.get(i);
			blockVO.setLayoutId(layoutId);
			blockServiceImpl.addBlock(moduleVO,blockVO);
		}
		
		// 增加明细对象布局,先删后增
		if (layoutVO.getItemLayout() != null && layoutVO.getItemLayout().size() > 0) {
			ModuleVO itemModuleVO = moduleServiceImpl.getModule(layoutVO.getObjId()).getItem();
			itemLayoutServiceImpl.deleteItemLayout(layoutId, itemModuleVO.getId());
			itemLayoutServiceImpl.saveItemLayout( layoutVO,itemModuleVO);
		}
		
		// 新增相关对象布局,先删后增
		if (layoutVO.getRelationLayout() != null && layoutVO.getRelationLayout().size() > 0) {
			for (int i =0 ; i < layoutVO.getRelationLayout().size() ; i++) {
				RelationLayoutVO relationLayoutVO = layoutVO.getRelationLayout().get(i);
				relationLayoutVO.setLayoutId(layoutId);
			}
			relationLayoutBizServiceImpl.deleteLayouts(layoutId);
			relationLayoutBizServiceImpl.addLayouts(layoutVO.getRelationLayout());
		}
		return layoutVO;
	}
	
	private Long getNextId() {
		return customIdGeneratorBizServiceImpl.getId();
	}
	
	public void saveLayoutAssignment(Integer clientType, Integer layoutType,List<LayoutAssignmentVO> assignmentVOs) {
		// TODO获取可用模板的时候可能是以终端类型和布局类型为分组来进行。要注意和系统预置值之间的关系。
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		Map<String, Object> assignMap = new HashMap<String, Object>();
		assignMap.put("tenantId", tenantId);
		assignMap.put("clientType", clientType);
		assignMap.put("layoutType", layoutType);
		assignMap.put("assignments", assignmentVOs);
		// 删除原来的配置
		dao.deleteSql(LayoutAssignmentVO.class, "deleteAllItems",	assignMap);
		// 重新分配
		dao.saveSql(LayoutAssignmentVO.class, "insertLayoutAssignment", assignMap);
	}

	/**
	 * 获取当前用户模板
	 * 
	 * @return
	 */
	public  LayoutVO getLayoutForCurrentUser(Long biztypeId,Integer clientType,Integer layoutType) {

		Map<String, Object> paramMap = new HashMap<String, Object>();
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		String roleIdStr = InvocationInfoProxy.getParameter(LoginContextConstant.RoleId);
		Long roleId = Long.parseLong(roleIdStr);
		
		paramMap.put("tenantId", tenantId);
		paramMap.put("biztypeId", biztypeId);
		paramMap.put("clientType", clientType);
		paramMap.put("layoutType", layoutType);
		paramMap.put("roleId", roleId);
		List<LayoutAssignmentVO> assignmentVOs= dao.selectVoList(LayoutAssignmentVO.class, "ListLayoutAssignment", paramMap);
		
		LayoutVO layoutVO = null;
		LayoutAssignmentVO layoutAssignmentVO = null;
		for (LayoutAssignmentVO assignmentVO : assignmentVOs) {
			layoutAssignmentVO = assignmentVO;
			if (assignmentVO.getTenantId() != 0) {
				break;
			}
		}
		if (layoutAssignmentVO == null) {
			BiztypeVO biztypeVO = biztypeBizServiceImpl.getBiztype(biztypeId);
			layoutVO = getDefaultLayout(biztypeVO.getObjId(), clientType, layoutType);
		} else {
			layoutVO = getLayout(layoutAssignmentVO.getLayoutId());
		}
		return layoutVO;
	}
	
	public LayoutVO getDefaultLayout(Long objId,Integer clientType,Integer layoutType) {
		List<LayoutVO> layoutVOs = getLayoutList(objId);
		LayoutVO defaultLayoutVO = null;
		for (LayoutVO layoutVO:layoutVOs) {
			if (layoutVO.getIsDefault() == 1 && layoutVO.getClientType()==clientType && layoutVO.getType() == layoutType) {
				defaultLayoutVO =getLayout(layoutVO.getId());
			}
		}
		if (defaultLayoutVO == null) {
			throw new CrmBusinessException("未设置默认模板");
		}
		return defaultLayoutVO;
	}
	
	public void deleteLayoutByBiztypeId(Long biztypeId) {
		// TODO获取可用模板的时候可能是以终端类型和布局类型为分组来进行。要注意和系统预置值之间的关系。
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("tenantId", tenantId);
		paramMap.put("biztypeId", biztypeId);
		dao.deleteSql(LayoutAssignmentVO.class, "deleteByBiztypeId",	paramMap);
	}
	
	@EventListener
	public void onBiztypeDelete(BiztypeDeleteEvent event) {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		paramMap.put("tenantId", tenantId);
		paramMap.put("biztypeId", event.getBiztype().getId());
		dao.deleteSql(LayoutAssignmentVO.class, "deleteByBiztypeId",	paramMap);
	}
	
	@EventListener
	public void onFieldDelete(FieldDeleteEvent event) {
		// 对级联字段的判断比较麻烦，需要判断是否有作为中间字段用到，即本字段没在模板中使用，但是作为中间字段为别的字段使用了，
		// 当前没有级联字段，暂时不管，只用actualField来做判断
		FieldVO fieldVO = event.getField();
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("actualField", fieldVO.getFullname());
		// 处理主对象列表
		List<LayoutVO> layoutList = dao.selectVoList(LayoutVO.class, "ListLayoutUsingField", paramMap);
		if (layoutList.size() > 0) {
			List<String> layoutNames = new ArrayList<String>();
			for (LayoutVO layoutVO : layoutList) {
				layoutNames.add(layoutVO.getName());
			}
			String layouts = StringUtils.collectionToCommaDelimitedString(layoutNames);		
			String msg = "模板"+layouts+"用到了该字段，请先将字段从模板中移除";
			throw new CrmBusinessException(msg);
		}
		// 处理明细对象列表
		layoutList = dao.selectVoList(LayoutVO.class, "ListLayoutByItemUsingField", paramMap);
		if (layoutList.size() > 0) {
			List<String> layoutNames = new ArrayList<String>();
			for (LayoutVO layoutVO : layoutList) {
				layoutNames.add(layoutVO.getName());
			}
			String layouts = StringUtils.collectionToCommaDelimitedString(layoutNames);		
			String msg = "模板"+layouts+"用到了该字段，请先将字段从模板中移除";
			throw new CrmBusinessException(msg);
		}
	}
	
	public void  deleteLayout(Long id) {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		String userIdStr = (String)InvocationInfoProxy.getParameter("id");//用户id
		Long userId = Long.parseLong(userIdStr);
		paramMap.put("tenantId", tenantId);
		paramMap.put("id", id);
		LayoutVO originalLayout = getLayout(id);
		Date now = new Date();
		if (originalLayout == null) {
			throw new CrmBusinessException("页面布局不存在");
		} else  {
			deletionCheck(originalLayout);
			originalLayout.setSysModifiedUserId(userId);
			originalLayout.setIsDeleted(1);
			originalLayout.setSysModifiedTime(now);
			if( originalLayout.getTenantId() == 0) {
			originalLayout.setTenantId(tenantId);
			originalLayout.setSysCreatedTime(now);
			originalLayout.setSysCreatedUserId(userId);
			super.saveVO(originalLayout);
			} else {
				super.updateVO(originalLayout);
			}
		}
		deleteLayoutAuxiliary(originalLayout);
	}
	
	private void deletionCheck(LayoutVO layoutVO) {
		String userIdStr = (String)InvocationInfoProxy.getParameter("id");//用户id
		Long userId = Long.parseLong(userIdStr);
		if (!administratorManage.isAdmin(userId)) {
			throw new CrmBusinessException("没有该功能的操作权限");
		}
		if (layoutVO.getIsDefault() == 1) {
			throw new CrmBusinessException("不能删除默认布局");
		}
	}
	
	private void deleteLayoutAuxiliary(LayoutVO layout) {
		// 删除主对象布局
		blockServiceImpl.deleteAllBlocks(layout.getId());
		// 删除明细布局
		ModuleVO moduleVO = moduleBizServiceImpl.getModule(layout.getObjId());
		if (moduleVO.getItem() != null) {
			itemLayoutServiceImpl.deleteItemLayout(layout.getId(), moduleVO.getItem().getId());
		}
		// 删除相关对象布局
		relationLayoutBizServiceImpl.deleteLayouts(layout.getId());
	}
	
	private void transformForClient(LayoutVO layoutVO) {
		// 处理主布局
		List<BlockVO> blockVOs = layoutVO.getMainLayout();
		for (int i =0;i<blockVOs.size();i++) {
			BlockVO blockVO = blockVOs.get(i);
			List<Integer> rowFlag = new ArrayList<Integer>();
			List<List<BlockItemVO> > blockitemsForClientList = new ArrayList<List<BlockItemVO>>();
			for (Integer  j=0;j<blockVO.getItems().size();j++) {
				BlockItemVO item = blockVO.getItems().get(j);
				Integer row = item.getRowPosition();
				if (!rowFlag.contains(row)) {
					rowFlag.add(row);
					List<BlockItemVO> blockItemVOs = new ArrayList<BlockItemVO>();
					blockItemVOs.add(item);
					blockitemsForClientList.add(blockItemVOs);
				}	else {
					blockitemsForClientList.get(blockitemsForClientList.size()-1).add(item);
				}	
			}
			blockVO.setItemsForClient(blockitemsForClientList);
		} 
		// 处理明细布局
		if (layoutVO.getItemLayout() != null) {
			List<ItemLayoutItemVO> itemLayoutItemVOs = layoutVO.getItemLayout();
			List<Integer> rowFlag = new ArrayList<Integer>();
			List<List<ItemLayoutItemVO> > itemsForClient = new ArrayList<List<ItemLayoutItemVO>>();
			for (Integer  j=0;j<itemLayoutItemVOs.size();j++) {
					ItemLayoutItemVO item = itemLayoutItemVOs.get(j);
					Integer row = item.getRowPosition();
					if (!rowFlag.contains(row)) {
						rowFlag.add(row);
						List<ItemLayoutItemVO> itemVOs = new ArrayList<ItemLayoutItemVO>();
						itemVOs.add(item);
						itemsForClient.add(itemVOs);
					}	else {
						itemsForClient.get(itemsForClient.size()-1).add(item);
					}	
			}
			layoutVO.setItemLayoutForClient(itemsForClient);
		}
	}
	
	/**
	 * 移动端的编辑布局。
	 */
	public TemplatesVO getMobileEditTemplateForCurrentUser(Long biztypeId) {
		LayoutVO layoutVO = getLayoutForCurrentUser(biztypeId, ClientType.MOBILE.getIndex(), LayoutType.EDIT.getIndex());
		return layoutToMobileEditTemplate(layoutVO);
	}
	
	/**
	 * 移动端的详情布局。
	 */
	public Map<String, List<DetailsGroupVO> > getMobileDetailTemplateForCurrentUser(Long biztypeId) {
		Map<String, List<DetailsGroupVO>> rsMap = new HashMap<String, List<DetailsGroupVO>>();
		List<DetailsGroupVO> headerlist = new ArrayList<DetailsGroupVO>();
		List<DetailsGroupVO> bodylist = new ArrayList<DetailsGroupVO>();
		LayoutVO layoutVO = getLayoutForCurrentUser(biztypeId, ClientType.MOBILE.getIndex(), LayoutType.VIEW.getIndex());
		layoutToMobileDetailTemplate(layoutVO,headerlist,bodylist);
		rsMap.put("header",headerlist);
		rsMap.put("body", bodylist);
		return rsMap;
	}
	
	private TemplatesVO layoutToMobileEditTemplate(LayoutVO layout) {
		TemplatesVO templatesVO = new TemplatesVO();
		 // 处理headerlist
		ArrayList<TemplatesHeaderVO> headerlist = mainLayoutToTemplatesHeaderlist(layout);
		 templatesVO.setHeaderlist(headerlist);
		 // 处理bodylist
		 ArrayList<TemplatesBodyVO> bodylist = itemLayoutToBodylist(layout);
		 if (bodylist == null) {
			 bodylist = new ArrayList<TemplatesBodyVO>();
		 }
		 templatesVO.setBodylist(bodylist);
		 // 处理triggerlist和filterlist
		 ArrayList<TemplatesTriggerVO> triggerlist = new ArrayList<TemplatesTriggerVO>();
		 ArrayList<TemplatesFilterVO> filterlist = new ArrayList<TemplatesFilterVO>();
		 assembleTriggerFilterList(layout, triggerlist, filterlist);
		 templatesVO.setTriggerlist(triggerlist);
		 templatesVO.setFilterlist(filterlist);
		return templatesVO;
	}
	
	private ArrayList<TemplatesHeaderVO> mainLayoutToTemplatesHeaderlist(LayoutVO layout) {
		 ArrayList<TemplatesHeaderVO> headerlist = new ArrayList<>();
		 List<BlockVO> blockVOs = layout.getMainLayout();
		 for (int i =0;i<blockVOs.size();i++) {
			 BlockVO blockVO = blockVOs.get(i);
			 TemplatesHeaderVO templatesHeaderVO = blockVOToTemplatesHeaderVO(blockVO);
			 headerlist.add(templatesHeaderVO);
		 }
		 return headerlist;
	}
	
	private TemplatesHeaderVO blockVOToTemplatesHeaderVO(BlockVO blockVO) {
		TemplatesHeaderVO templatesHeaderVO = new TemplatesHeaderVO();
		//templatesHeaderVO.setHeadername(blockVO.getName());
		templatesHeaderVO.setHeadername("");
		templatesHeaderVO.setStyle("");
		ArrayList<TemplatesItemVO> templatesItemVOs = new ArrayList<TemplatesItemVO>();
		for (int i=0;i<blockVO.getItems().size();i++) {
			BlockItemVO blockItemVO = blockVO.getItems().get(i);
			// 占位元素直接跳过，这种情况在移动端详情布局不应该出现
			if (blockItemVO.getIsBlank() == 1) {
				continue;
			}
			FieldVO actualField = blockItemVO.getActualField();
			TemplatesItemVO templatesItemVO = new TemplatesItemVO();
			templatesItemVO.setItemkey(blockItemVO.getApiName());
			templatesItemVO.setItemname(blockItemVO.getName());
			templatesItemVO.setItemtype(actualField.getMobileUiType());
			Integer isEditable = (blockItemVO.getIsReadonly()!=null &&blockItemVO.getIsReadonly() ==1)? 0: 1;
			templatesItemVO.setIseditable(objectToYN(isEditable));
			templatesItemVO.setIsrequired(objectToYN(blockItemVO.getIsRequired()));
			
			templatesItemVO.setIsmultiselect(objectToYN(isMultiSelect(actualField)));
			templatesItemVO.setMaxpicnum(actualField.getLength().toString());
			templatesItemVO.setIssurportalbum(objectToYN(actualField.getIsSupportAlbum()));
			templatesItemVO.setPrecision(actualField.getPrecision().toString());
//			templatesItemVO.setIsdisplay("Y");
			templatesItemVO.setIsdisplay(actualField.getIsDisplayable()==1? "Y":"N");
			templatesItemVO.setMaxlenth(actualField.getLength().toString());
			
			if (actualField.getType() == FieldType.Lookup || actualField.getType() == FieldType.MasterDetail) {
				ModuleVO moduleVO = moduleBizServiceImpl.getModule(actualField.getRefObjId());
				templatesItemVO.setReferto(moduleVO.getApiName());
			} else {
				templatesItemVO.setReferto("");
			}		
			templatesItemVO.setEditformula(actualField.getExpression());
			ArrayList<TemplatesEnumVO> enumdatalist = new ArrayList<TemplatesEnumVO>();
			if (actualField.getEnums()  != null) {
				for (Map<String, Object> enumMap:actualField.getEnums() )  {
					enumdatalist.add(new TemplatesEnumVO(enumMap.get("key").toString(),enumMap.get("title").toString()));
				}
			} else if (actualField.getOriginalDoc() != null) {
				BaseDocVO baseDocVO = actualField.getOriginalDoc();
				for (BaseDocDetailVO baseDocDetailVO:baseDocVO.getBaseDocDetailList()) {
					enumdatalist.add(new TemplatesEnumVO(baseDocDetailVO.getId().toString(),baseDocDetailVO.getName()));
				}
			}
			templatesItemVO.setEnumdatalist(enumdatalist);
			templatesItemVOs.add(templatesItemVO);
			templatesHeaderVO.setItemlist(templatesItemVOs);
		}
		return templatesHeaderVO;
	}
	
	private  ArrayList<TemplatesBodyVO>  itemLayoutToBodylist(LayoutVO layoutVO) {
		List<ItemLayoutItemVO> items = layoutVO.getItemLayout();
		if (items == null) {
			return null;
		}
		ModuleVO itemModuleVO = moduleBizServiceImpl.getItemModule(layoutVO.getObjId());
		ArrayList<TemplatesBodyVO> templatesBodyVOs = new ArrayList<TemplatesBodyVO>();
		TemplatesBodyVO templatesBodyVO = new TemplatesBodyVO();
		templatesBodyVO.setBodymark(itemModuleVO.getApiName());
		templatesBodyVO.setBodyname(itemModuleVO.getName());
		templatesBodyVO.setStyle("");
		ArrayList<TemplatesItemVO> templatesItemVOs = new ArrayList<TemplatesItemVO>();
		for (int i=0;i<items.size();i++) {
			TemplatesItemVO templatesItemVO = new TemplatesItemVO();
			ItemLayoutItemVO itemLayoutItemVO = items.get(i);
			// 占位元素直接跳过，这种情况在移动端详情布局不应该出现
			if (itemLayoutItemVO.getIsBlank() == 1) {
				continue;
			}
			FieldVO actualField = itemLayoutItemVO.getActualField();
			templatesItemVO.setItemkey(itemLayoutItemVO.getApiName());
			templatesItemVO.setItemname(itemLayoutItemVO.getName());
			templatesItemVO.setItemtype(actualField.getMobileUiType());
			Integer isEditable = (itemLayoutItemVO.getIsReadonly() ==1) ? 0: 1;
			templatesItemVO.setIseditable(objectToYN(isEditable));
			templatesItemVO.setIsrequired(objectToYN(itemLayoutItemVO.getIsRequired()));
			templatesItemVO.setIsmultiselect(objectToYN(isMultiSelect(actualField)));
			templatesItemVO.setMaxpicnum(actualField.getLength().toString());
			templatesItemVO.setIssurportalbum(objectToYN(actualField.getIsSupportAlbum()));
			templatesItemVO.setPrecision(itemLayoutItemVO.getActualField().getPrecision().toString());
			templatesItemVO.setIsdisplay("Y");
			templatesItemVO.setMaxlenth(itemLayoutItemVO.getActualField().getLength().toString());
			if (actualField.getType() == FieldType.Lookup || actualField.getType() == FieldType.MasterDetail) {
				ModuleVO moduleVO = moduleBizServiceImpl.getModule(actualField.getRefObjId());
				templatesItemVO.setReferto(moduleVO.getApiName());
			} else {
				templatesItemVO.setReferto("");
			}		
			templatesItemVO.setEditformula(actualField.getExpression());
			ArrayList<TemplatesEnumVO> enumdatalist = new ArrayList<TemplatesEnumVO>();
			if (actualField.getEnums()  != null) {
				for (Map<String, Object> enumMap:actualField.getEnums() )  {
					enumdatalist.add(new TemplatesEnumVO(enumMap.get("key").toString(),enumMap.get("title").toString()));
				}
			} else if (actualField.getOriginalDoc() != null) {
				BaseDocVO baseDocVO = actualField.getOriginalDoc();
				for (BaseDocDetailVO baseDocDetailVO:baseDocVO.getBaseDocDetailList()) {
					enumdatalist.add(new TemplatesEnumVO(baseDocDetailVO.getId().toString(),baseDocDetailVO.getName()));
				}
			}
			templatesItemVO.setEnumdatalist(enumdatalist);
			templatesItemVOs.add(templatesItemVO);
		}
		templatesBodyVO.setItemlist(templatesItemVOs);
		// 目前只支持最多一个明细
		templatesBodyVOs.add(templatesBodyVO);
		return templatesBodyVOs;
	}

	private void assembleTriggerFilterList(LayoutVO layout,List<TemplatesTriggerVO> triggerlist,
			List<TemplatesFilterVO> filterlist) {
		 List<BlockVO> blockVOs = layout.getMainLayout(); 
		 Map<String,List<TemplatesParttakeVO>>  mainEffectlistMap = new HashMap<String,List<TemplatesParttakeVO>>();
		 Map<String,List<TemplatesParttakeVO>>  itemEffectlistMap = new HashMap<String,List<TemplatesParttakeVO>>();
		 
		 // 主对象
		 for (BlockVO blockVO:blockVOs) {
			 List<BlockItemVO> blockItemVOs = blockVO.getItems();
			 for ( BlockItemVO blockItemVO:blockItemVOs) {
				 if (blockItemVO.getIsBlank() == 1) {
					 continue;
				 }
				 FieldVO actualField = blockItemVO.getActualField();
				 List<TemplatesParttakeVO> necessarylist = new ArrayList<TemplatesParttakeVO>();
				 List<TemplatesParttakeVO> parttakelist = new ArrayList<TemplatesParttakeVO>();
				 
				 if (actualField.getControlledBy() != null && actualField.getControlledBy().length >0) {
					 for (String fieldStr:actualField.getControlledBy()) {	 
						 // 处理被影响项
						 // controlledby里不应该出现__login__打头的数据项
						 TemplatesParttakeVO effect = fieldStrToEffectiveVO(true,fieldStr,actualField.getApiName());
						 if (mainEffectlistMap.containsKey(fieldStr)) {
							 List<TemplatesParttakeVO> effectList = mainEffectlistMap.get(fieldStr);
							 effectList.add(effect);
						 } else {
							 List<TemplatesParttakeVO> effectList = new ArrayList<TemplatesParttakeVO>();
							 effectList.add(effect);
							 mainEffectlistMap.put(fieldStr, effectList);
						 }
						 TemplatesParttakeVO necessary = fieldStrToNecessaryVO(true,fieldStr);
						 necessarylist.add(necessary);
					 }
				 }
				 
				 if (actualField.getMobileApi() != null) {
					 TemplatesFilterVO templatesFilterVO = new TemplatesFilterVO();
					 ApiVO mobileApiVO = actualField.getMobileApi();
					 templatesFilterVO.setItemkey(actualField.getApiName());
					 if (necessarylist.size()>0) {
						 templatesFilterVO.setNecessarylist(necessarylist);					 
					 }
					 if (mobileApiVO.getFilterFields() != null && mobileApiVO.getFilterFields().length>0) {
						 for (String fieldStr:mobileApiVO.getFilterFields()) {
							 TemplatesParttakeVO templatesParttakeVO  = fieldStrToTemplatesParttakeVO(true,fieldStr);
							 parttakelist.add(templatesParttakeVO);
						 }
					 }
					 templatesFilterVO.setParttakelist(parttakelist);
					 if (necessarylist.size() > 0 || parttakelist.size()>0 ) {
						 filterlist.add(templatesFilterVO);
					 }
				 }
				 if (necessarylist.size() > 0 || parttakelist.size()>0) {
					 TemplatesTriggerVO templatesTriggerVO = new TemplatesTriggerVO();
					 templatesTriggerVO.setBodymark("");
					 templatesTriggerVO.setItemkey(blockItemVO.getApiName());
					 List<TemplatesParttakeVO> triggerNecessarylist = new ArrayList<TemplatesParttakeVO>();
					 List<TemplatesParttakeVO> triggerParttakelist = new ArrayList<TemplatesParttakeVO>();
					 // 过滤parttakelist、necessarylist里的以__login__.开头的字段或itemkey为空的数据
					 filterDataForTrigger(necessarylist, triggerNecessarylist);
					 filterDataForTrigger(parttakelist, triggerParttakelist);
					 templatesTriggerVO.setNecessarylist(triggerNecessarylist);
					 templatesTriggerVO.setParttakelist(triggerParttakelist);
					 if (actualField.getMobileApi() != null) {
						 List<String> typeList = new ArrayList<String>();
						 String filter = actualField.getMobileApi().getFilter();
						 if (filter != "") {
							 typeList.add(filter);
							 templatesTriggerVO.setType(typeList);
						 }
					 } 
					 triggerlist.add(templatesTriggerVO);
				 }
			 }
		 }
		 // 明细对象
		 List<ItemLayoutItemVO> itemLayoutItemVOs = layout.getItemLayout();
		 ModuleVO itemModuleVO = moduleBizServiceImpl.getItemModule(layout.getObjId());
		 if (itemLayoutItemVOs != null) {
			 for (ItemLayoutItemVO itemLayoutItemVO:itemLayoutItemVOs) {
				 FieldVO actualField = itemLayoutItemVO.getActualField();
				 List<TemplatesParttakeVO> necessarylist = new ArrayList<TemplatesParttakeVO>();
				 List<TemplatesParttakeVO> parttakelist = new ArrayList<TemplatesParttakeVO>();
				 if (actualField.getControlledBy() != null && actualField.getControlledBy().length >0) {
					 for (String fieldStr:actualField.getControlledBy()) {
						 // 处理被影响项
						 // controlledby里不应该出现__login__打头的数据项
						 TemplatesParttakeVO effect = fieldStrToEffectiveVO(false,fieldStr,actualField.getApiName());
						 if (fieldStr.startsWith("__Main__")) {
							 String mainField = fieldStr.substring("__Main__.".length());
							 if (mainEffectlistMap.containsKey(mainField)) {
								 List<TemplatesParttakeVO> effectList = mainEffectlistMap.get(mainField);
								 effectList.add(effect);
							 } else {
								 List<TemplatesParttakeVO> effectList = new ArrayList<TemplatesParttakeVO>();
								 effectList.add(effect);
								 mainEffectlistMap.put(mainField, effectList);
							 }
						 } else {
							 if (itemEffectlistMap.containsKey(fieldStr)) {
								 List<TemplatesParttakeVO> effectList = itemEffectlistMap.get(fieldStr);
								 effectList.add(effect);
							 } else {
								 List<TemplatesParttakeVO> effectList = new ArrayList<TemplatesParttakeVO>();
								 effectList.add(effect);
								 itemEffectlistMap.put(fieldStr, effectList);
							 }
						 }
						 TemplatesParttakeVO necessary = fieldStrToNecessaryVO(false,fieldStr);
						 necessarylist.add(necessary);
					 }
				 }
				 if (actualField.getMobileApi() != null) {
					 TemplatesFilterVO templatesFilterVO = new TemplatesFilterVO();
					 ApiVO mobileApiVO = actualField.getMobileApi();
					 templatesFilterVO.setItemkey(actualField.getApiName());
					 if (necessarylist.size()>0) {
						 templatesFilterVO.setNecessarylist(necessarylist);					 
					 }
					 if (mobileApiVO.getFilterFields() != null && mobileApiVO.getFilterFields().length>0) {
						 for (String fieldStr:mobileApiVO.getFilterFields()) {
							 TemplatesParttakeVO templatesParttakeVO  = fieldStrToTemplatesParttakeVO(true,fieldStr);
							 parttakelist.add(templatesParttakeVO);
						 }
					 }
					 templatesFilterVO.setParttakelist(parttakelist);
					 if (necessarylist.size() > 0 || parttakelist.size()>0 ) {
						 filterlist.add(templatesFilterVO);
					 }
				 }
				 if (necessarylist.size() > 0 || parttakelist.size()>0) {
					 TemplatesTriggerVO templatesTriggerVO = new TemplatesTriggerVO();
					 templatesTriggerVO.setBodymark(itemModuleVO.getApiName());
					 templatesTriggerVO.setItemkey(itemLayoutItemVO.getApiName());
					 List<TemplatesParttakeVO> triggerNecessarylist = new ArrayList<TemplatesParttakeVO>();
					 List<TemplatesParttakeVO> triggerParttakelist = new ArrayList<TemplatesParttakeVO>();
					 // 过滤parttakelist、necessarylist里的以__login__.开头的字段或itemkey为空的数据
					 filterDataForTrigger(necessarylist, triggerNecessarylist);
					 filterDataForTrigger(parttakelist, triggerParttakelist);
					 templatesTriggerVO.setNecessarylist(triggerNecessarylist);
					 templatesTriggerVO.setParttakelist(triggerParttakelist);
					 List<String> typeList = new ArrayList<String>();
					 if (actualField.getMobileApi() != null) {
						 String filter = actualField.getMobileApi().getFilter();
						 if (filter != "") {
							 typeList.add(filter);
							 templatesTriggerVO.setType(typeList);
						 }
					 } 
					 triggerlist.add(templatesTriggerVO);
				 }				 
			 }
		 }
		 // 处理被影响项
		 mergeEffectMapToTriggerList(mainEffectlistMap,itemEffectlistMap,triggerlist,itemModuleVO);
	}
	
	/**
	 * 过滤parttakelist、necessarylist里的以__login__.开头的字段或itemkey为空的数据
	 * @param list
	 * @param triggerList
	 */
	private void filterDataForTrigger (List<TemplatesParttakeVO> list, List<TemplatesParttakeVO> triggerList) {
		// 过滤necessarylist里的以__login__.开头的字段或itemkey为空的数据
		 for(TemplatesParttakeVO item : list) {
			 if (item != null && item.getItemkey() != null) {
				 String itemKey = item.getItemkey();
				 if (itemKey.equals("") || itemKey.startsWith("__Login__.")) {
					 continue;
				 }
				 triggerList.add(item);
			 }
		 }
	}
		
	private Boolean isMultiSelect(FieldVO fieldVO) {
		if ( fieldVO.getType() == FieldType.MultiSelect) {
			return true;
		} else {
			return false;
		}
	}
	
	private void mergeEffectMapToTriggerList(Map<String , List<TemplatesParttakeVO>> mainEffectMap,
			Map<String , List<TemplatesParttakeVO>> itemEffectMap,
			List<TemplatesTriggerVO> triggerlist,
			ModuleVO itemModule) {
		 for (Map.Entry<String , List<TemplatesParttakeVO>> entry: mainEffectMap.entrySet()) {
			 TemplatesTriggerVO templatesTriggerVO = getTemplatesTriggerVO(triggerlist,true,entry.getKey());
			 if (templatesTriggerVO == null)  {
				 templatesTriggerVO = new TemplatesTriggerVO();
				 templatesTriggerVO.setBodymark("");
				 templatesTriggerVO.setItemkey(entry.getKey());
				 triggerlist.add(templatesTriggerVO);
				 templatesTriggerVO.setEffectlist(entry.getValue());
			 } else {
				 templatesTriggerVO.setEffectlist(entry.getValue());
			 }
		 }
		 
		 for (Map.Entry<String , List<TemplatesParttakeVO>> entry: itemEffectMap.entrySet()) {
			 TemplatesTriggerVO templatesTriggerVO = getTemplatesTriggerVO(triggerlist,false,entry.getKey());
			 if (templatesTriggerVO == null)  {
				 templatesTriggerVO = new TemplatesTriggerVO();
				 templatesTriggerVO.setBodymark(itemModule.getApiName());
				 templatesTriggerVO.setItemkey(entry.getKey());
				 templatesTriggerVO.setEffectlist(entry.getValue());
				 triggerlist.add(templatesTriggerVO);
			 } else {
				 templatesTriggerVO.setEffectlist(entry.getValue());
			 }
		 }
	}
	
	private TemplatesTriggerVO getTemplatesTriggerVO(List<TemplatesTriggerVO> triggerlist,boolean isMain, String itemKey) {
		if (triggerlist == null || triggerlist.size() ==0) {
			return null;
		}
		for(TemplatesTriggerVO templatesTriggerVO:triggerlist) {
			if ((isMain && templatesTriggerVO.getBodymark()=="" && templatesTriggerVO.getItemkey().equals(itemKey) ) 
				|| (!isMain && templatesTriggerVO.getBodymark()!="" && templatesTriggerVO.getItemkey().equals(itemKey) )
				){
				return templatesTriggerVO;
			}
		}
		return null;
	}
	
	/**
	 * 模板分配模板
	 */
	public Map<String, Object> getAssignmentTemplate(Long objId, Integer clientType,Integer layoutType ) {
		
		Map<String, Object> paramMap = new HashMap<String, Object>();
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		// 业务类型列表
		List<BiztypeVO> biztypeVOs = biztypeBizServiceImpl.getBiztypeList(objId);
		List<Map<String, Object>> biztypeMaps = new ArrayList<Map<String,Object>>();
		for (BiztypeVO biztypeVO:biztypeVOs) {
			Map<String, Object> biztypeMap = new HashMap<String, Object>();
			biztypeMap.put("id", biztypeVO.getId());
			biztypeMap.put("name", biztypeVO.getName());
			biztypeMaps.add(biztypeMap);
		}
		// 角色列表
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("tenantId", new Long(tenantId));
		List<RoleVO> roleVOs = roleBizServiceImpl.getRoleListByTenantId(param);
		List<Map<String, Object>> roleMaps = new ArrayList<Map<String,Object>>();
		for (RoleVO roleVO: roleVOs) {
			Map<String, Object> roleMap = new HashMap<String, Object>();
			roleMap.put("id", roleVO.getId());
			roleMap.put("name", roleVO.getName());
			roleMaps.add(roleMap);
		}
		// 布局分配
		paramMap.put("tenantId", tenantId);
		paramMap.put("clientType", clientType);
		paramMap.put("layoutType", layoutType);
		List<LayoutAssignmentVO> assignmentVOs = dao.selectVoList(LayoutAssignmentVO.class, "ListLayoutAssignment", paramMap);
		Map<String, Object> assignments = new HashMap<String, Object>();
		LayoutVO defaultLayoutVO = getDefaultLayout(objId, clientType, layoutType);
		Map<String, Object> defaultLayoutMap = new HashMap<String, Object>();
		defaultLayoutMap.put("id", defaultLayoutVO.getId());
		defaultLayoutMap.put("name", defaultLayoutVO.getName());
		for (LayoutAssignmentVO layoutAssignmentVO:assignmentVOs) {
			String keyString = layoutAssignmentVO.getRoleId() + "-" + layoutAssignmentVO.getBiztypeId();
			// TODO 改成批量取数据，或者做缓存
			LayoutVO layoutVO = getPrimitiveLayout(layoutAssignmentVO.getLayoutId());
			Map<String, Object> layoutMap = new HashMap<String, Object>();
			layoutMap.put("id", layoutVO.getId());
			layoutMap.put("name", layoutVO.getName());
			assignments.put(keyString, layoutMap);
		}

		for (RoleVO roleVO: roleVOs) {
			List<BiztypeVO> availableBiztypeVOs = biztypeBizServiceImpl.getBiztypeListByRoleId(objId, roleVO.getId());
			List<Long> availableBiztypeIdList = new ArrayList<Long>();
			for (BiztypeVO biztypeVO:availableBiztypeVOs) {
				availableBiztypeIdList.add(biztypeVO.getId());
			}
			for (BiztypeVO biztypeVO:biztypeVOs) {
				String keyString = roleVO.getId() + "-" + biztypeVO.getId();
				if (!assignments.containsKey(keyString) && availableBiztypeIdList.contains(biztypeVO.getId())) {
					assignments.put(keyString, defaultLayoutMap);
				} else if(!assignments.containsKey(keyString) && !availableBiztypeIdList.contains(biztypeVO.getId())) {
					assignments.put(keyString,null);
				}
			}
		}
		Map<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.put("roles", roleMaps);
		resultMap.put("biztypes", biztypeMaps);
		resultMap.put("assignments", assignments);
		return resultMap;
	}
	
	private LayoutVO getPrimitiveLayout(Long id) {
		Map<String, Object> paramMap = new HashMap<String, Object>();
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		paramMap.put("tenantId", tenantId);
		paramMap.put("id", id);
		List<LayoutVO> layoutList = new ArrayList<LayoutVO>();
		layoutList = dao.selectVoList(LayoutVO.class, "ListLayout", paramMap);
		LayoutVO layoutVO = null;
		Iterator<LayoutVO> it = layoutList.iterator();
		while (it.hasNext()) {
			layoutVO  = it.next();
			if (layoutVO.getTenantId() != 0) {
				break;
			}
		}
		return layoutVO;
	}
	
	private void layoutToMobileDetailTemplate(LayoutVO layout,List<DetailsGroupVO> headerlist,List<DetailsGroupVO> bodylist) {
		 // 处理headerlist
		List<DetailsGroupVO> detailsGroupVOs = mainLayoutToDetailTemplatesHeaderlist(layout);
		headerlist.addAll(detailsGroupVOs);
		 // 处理bodylist
		List<DetailsGroupVO> detailsGroupList  = itemLayoutToDetailBodylist(layout);
		if (detailsGroupList != null) {
			bodylist.addAll(detailsGroupList);
		}
	}
	

	private List<DetailsGroupVO> mainLayoutToDetailTemplatesHeaderlist(LayoutVO layout) {
		 ArrayList<DetailsGroupVO> headerlist = new ArrayList<>();
		 List<BlockVO> blockVOs = layout.getMainLayout();
		 for (int i =0;i<blockVOs.size();i++) {
			 BlockVO blockVO = blockVOs.get(i);
			 DetailsGroupVO detailsGroupVO = blockVOToDetailTemplatesHeaderVO(blockVO);
			 headerlist.add(detailsGroupVO);
		 }
		 return headerlist;
	}
	
	private DetailsGroupVO blockVOToDetailTemplatesHeaderVO(BlockVO blockVO) {
		DetailsGroupVO detailsGroupVO = new DetailsGroupVO();
		detailsGroupVO.setGroupname(blockVO.getName());
		detailsGroupVO.setGroupid(blockVO.getId().toString());
		 List<DetailsItemVO> groupdata = new ArrayList<DetailsItemVO>();
		for (int i=0;i<blockVO.getItems().size();i++) {
			BlockItemVO blockItemVO = blockVO.getItems().get(i);
			// 占位元素直接跳过，这种情况在移动端详情布局不应该出现
			if (blockItemVO.getIsBlank() == 1) {
				continue;
			}
			FieldVO actualField = blockItemVO.getActualField();
			DetailsItemVO detailsItemVO = new DetailsItemVO();
			detailsItemVO.setItemkey(blockItemVO.getApiName());
			detailsItemVO.setType(actualField.getMobileUiType());
			detailsItemVO.setName(blockItemVO.getName());
			groupdata.add(detailsItemVO);
		}
		detailsGroupVO.setGroupdata(groupdata);
		return detailsGroupVO;
	}
	
	private  List<DetailsGroupVO>  itemLayoutToDetailBodylist(LayoutVO layoutVO) {

		List<ItemLayoutItemVO> items = layoutVO.getItemLayout();
		if (items == null) {
			return null;
		}
		List<DetailsGroupVO> detailsGroupVOs = new ArrayList<DetailsGroupVO>();
		DetailsGroupVO detailsGroupVO = new DetailsGroupVO();
		ModuleVO itemModuleVO = moduleBizServiceImpl.getItemModule(layoutVO.getObjId());
		detailsGroupVO.setGroupid(itemModuleVO.getId().toString());
		detailsGroupVO.setGroupname(itemModuleVO.getName());
		List<DetailsItemVO> groupdata = new ArrayList<DetailsItemVO>();
		for (int i=0;i<items.size();i++) {
			ItemLayoutItemVO itemLayoutItemVO = items.get(i);
			// 占位元素直接跳过，这种情况在移动端详情布局不应该出现
			if (itemLayoutItemVO.getIsBlank() == 1) {
				continue;
			}
			FieldVO actualField = itemLayoutItemVO.getActualField();
			DetailsItemVO detailsItemVO = new DetailsItemVO();
			detailsItemVO.setItemkey(itemLayoutItemVO.getApiName());
			detailsItemVO.setName(itemLayoutItemVO.getName());
			detailsItemVO.setType(actualField.getMobileUiType());
			groupdata.add(detailsItemVO);
		}
		detailsGroupVO.setGroupdata(groupdata);
		// 目前只支持最多一个明细
		detailsGroupVOs.add(detailsGroupVO);
		return detailsGroupVOs;
	}	
	
	/**
	 * 移动端的编辑初始数据，不设置value。
	 */
	public InitDatasVO getInitDatasForMobile(Long biztypeId) {
		LayoutVO layoutVO = getLayoutForCurrentUser(biztypeId, ClientType.MOBILE.getIndex(), LayoutType.EDIT.getIndex());
		InitDatasVO initDatasVO = new InitDatasVO();
		ArrayList<InitDatasListItemVO> headerlist = new ArrayList<InitDatasListItemVO>();
		for (BlockVO block:layoutVO.getMainLayout()) {
			for (BlockItemVO blockItemVO:block.getItems()) {
				if (blockItemVO.getIsBlank() == 1) {
					continue;
				}
				InitDatasListItemVO initDatasListItemVO = new InitDatasListItemVO();
				initDatasListItemVO.setItemkey(blockItemVO.getApiName());
				ArrayList<InitDatasItemVO> itemDataList = new ArrayList<>();
				InitDatasItemVO initDatasItemVO = new InitDatasItemVO();
				itemDataList.add(initDatasItemVO);
				initDatasListItemVO.setItemdatalist(itemDataList);
				headerlist.add(initDatasListItemVO);
			}
		}
		ArrayList<InitDatasBodyVO> bodylist = new ArrayList<InitDatasBodyVO>();
		if (layoutVO.getItemLayout() != null) {
			String bodymark = "";
			InitDatasBodyVO initDatasBodyVO = new InitDatasBodyVO();
			List<List<InitDatasListItemVO>> bodydatalist = new ArrayList<List<InitDatasListItemVO>>();
			List<InitDatasListItemVO> initDatasListItemVOs = new ArrayList<InitDatasListItemVO>();
			
			InitDatasListItemVO initDatasListItemVO = new InitDatasListItemVO();

			for (ItemLayoutItemVO itemLayoutItemVO:layoutVO.getItemLayout()) {
				bodymark = itemLayoutItemVO.getItemObjId().toString();
				if (itemLayoutItemVO.getIsBlank() == 1) {
					continue;
				}
				initDatasListItemVO.setItemkey(itemLayoutItemVO.getApiName());
				//设置空itemdataList
				ArrayList<InitDatasItemVO> itemdatalist = new ArrayList<InitDatasItemVO>();
				itemdatalist.add(new InitDatasItemVO());
				initDatasListItemVO.setItemdatalist(itemdatalist);
				initDatasListItemVOs.add(initDatasListItemVO);

			}
			bodydatalist.add(initDatasListItemVOs);
			initDatasBodyVO.setBodydatalist(bodydatalist);
			initDatasBodyVO.setBodymark(bodymark);
			bodylist.add(initDatasBodyVO);
		}
		initDatasVO.setHeaderlist(headerlist);
		initDatasVO.setBodylist(bodylist);
		return initDatasVO;
	}
	
	public void saveLayoutDisableStatus(Long layoutId){
		LayoutVO layout = new LayoutVO();
		layout.setId(layoutId);
		layout.setEnableState(2);
		updateLayoutOnly(layout);
	}
	
	public void saveLayoutEnableStatus(Long layoutId){
		LayoutVO layout = new LayoutVO();
		layout.setId(layoutId);
		layout.setEnableState(1);
		updateLayoutOnly(layout);
	}
	
	private void updateLayoutOnly(LayoutVO layout) {
		String tenantIdStr = (String) InvocationInfoProxy.getTenantid();
		Long tenantId = Long.parseLong(tenantIdStr);
		String userIdStr = (String) InvocationInfoProxy.getParameter("id");// 用户id
		Long userId = Long.parseLong(userIdStr);

		layout.setTenantId(tenantId);
		LayoutVO originalLayout = getLayout(layout.getId());
		disableCheck(originalLayout);
		// 不是为了更新，而是为了返回用
		layout.setIsDefault(originalLayout.getIsDefault());
		Date date = new Date();
		layout.setEnableTime(date);
		layout.setEnableUserId(userId);
		layout.setModifiedTime(date);
		layout.setSysModifiedTime(date);
		layout.setSysModifiedUserId(userId);
		layout.setModifiedUserId(userId);

		if (originalLayout.getTenantId() == 0) {
			layout.setSysCreatedTime(date);
			layout.setCreatedTime(originalLayout.getCreatedTime());
			layout.setObjId(originalLayout.getObjId());
			layout.setSortOrder(originalLayout.getSortOrder());
			super.saveVO(layout);
		} else {
			super.updateVO(layout);
		}
	}
	
	private void disableCheck(LayoutVO layout) {
		String userIdStr = (String)InvocationInfoProxy.getParameter("id");//用户id
		Long userId = Long.parseLong(userIdStr);
		if (!administratorManage.isAdmin(userId)) {
			throw new CrmBusinessException("没有该功能的操作权限");
		}
		if (layout.getIsDefault() == 1) {
			throw new CrmBusinessException("不能停用默认业务类型");
		}
	}
}	
	

